package com.fadadianqi.logistics.sell.dao.ibatis;

import com.fadadianqi.commons.GenericDAOSuport;
import com.fadadianqi.logistics.sell.dao.BillDAO;
import com.fadadianqi.logistics.sell.model.Bill;
import com.yeqiangwei.commons.util.Pagination;
import com.yeqiangwei.commons.util.Pagination.Order;
import com.yeqiangwei.commons.util.ValidatorHelper;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class BillDAOImpl extends GenericDAOSuport<String, Bill> implements BillDAO {

    @Override
    protected Class<?> getObjectClass() {
        return Bill.class;
    }

    @Override
    protected String getTableName() {
        return "bill";
    }

    @Override
    public List<Bill> findAll(Pagination pagination) {
        return super.findAll(pagination);
    }

    @Override
    public List<Bill> findByVillageId(String villageId, Pagination pagination) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(Bill.PROP_VILLAGE_ID, villageId);
        map.put("pagination", pagination);
        return super.findByPropertys(map);
    }

    @Override
    public int countByVillageId(String villageId) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(Bill.PROP_VILLAGE_ID, villageId);
        return super.countAll(map);
    }

    @Override
    public List<Bill> findByCustomerId(String cid, Pagination pagination) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(Bill.PROP_CUSTOMER_ID, cid);
        map.put("pagination", pagination);
        return super.findByPropertys(map);
    }

    @Override
    public int countByCustomerId(String cid) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(Bill.PROP_CUSTOMER_ID, cid);
        return super.countAll(map);
    }

    @Override
    public int countByTownId(String tid) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(Bill.PROP_TOWN_ID, tid);
        return super.countAll(map);
    }

    @Override
    public List<Bill> findByTownId(String tid, Pagination pagination) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(Bill.PROP_TOWN_ID, tid);
        map.put("pagination", pagination);
        return super.findByPropertys(map);
    }

    @Override
    public int countAllWithIsReturn(Boolean isReturn) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(Bill.PROP_IS_RETURN, isReturn);
        return super.countAll(map);
    }

    @Override
    public List<Bill> findAllWithIsReturn(Boolean isReturn,
                                          Pagination pagination) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(Bill.PROP_IS_RETURN, isReturn);
        map.put("pagination", pagination);
        return super.findByPropertys(map);
    }

    @Override
    public List<Bill> findAllWithIsChecked(Boolean isChecked,
                                           Pagination pagination) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(Bill.PROP_IS_CHECKED, isChecked);
        map.put(Bill.PROP_IS_RETURN, Boolean.FALSE);
        map.put("pagination", pagination);
        return super.findByPropertys(map);
    }

    @Override
    public int countAllWithIsChecked(Boolean isChecked) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(Bill.PROP_IS_CHECKED, isChecked);
        map.put(Bill.PROP_IS_RETURN, Boolean.FALSE);
        return super.countAll(map);
    }

    @Override
    public Double sumCostBetween(Date date1, Date date2) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("date1", date1);
        map.put("date2", date2);
        Object sum = getSqlMapClientTemplate().queryForObject(getNamespace() + ".sumCostBetween", map);
        if (sum != null) {
            return (Double) sum;
        } else {
            return 0D;
        }
    }

    @Override
    public Double sumRealPayablesBetween(Date date1, Date date2) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("date1", date1);
        map.put("date2", date2);
        Object sum = getSqlMapClientTemplate().queryForObject(getNamespace() + ".sumRealPayablesBetween", map);
        if (sum != null) {
            return (Double) sum;
        } else {
            return 0D;
        }
    }

    @Override
    public int countAll() {
        return super.countAll(null);
    }

    @Override
    public Double sumRealPayables(int year) {
        Object sum = getSqlMapClientTemplate().queryForObject(
                getNamespace() + ".sumRealPayables", year);
        if (sum != null) {
            return (Double) sum;
        } else {
            return 0D;
        }
    }

    @Override
    public Double sumPurchase(int year) {
        Object sum = getSqlMapClientTemplate().queryForObject(
                getNamespace() + ".sumPurchase", year);
        if (sum != null) {
            return (Double) sum;
        } else {
            return 0D;
        }
    }

    @Override
    public Double sumCost(int year) {
        Object sum = getSqlMapClientTemplate().queryForObject(
                getNamespace() + ".sumCost", year);
        if (sum != null) {
            return (Double) sum;
        } else {
            return 0D;
        }
    }

    private List<Bill> between(Map<String, Object> map, Pagination pagination) {
        if (pagination != null) {
            map.put(START_ROW_NUM, pagination.getStartRows());
            map.put(MAX_ROW_NUM, pagination.getMaxResults());
            map.put(END_ROW_NUM, pagination.getStartRows() + pagination.getMaxResults());
            List<Order> orderList = pagination.getOrderList();
            if (ValidatorHelper.isNotEmpty(orderList)) {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < orderList.size(); i++) {
                    Order order = orderList.get(i);
                    sb.append(order.getName());
                    if (order.getAscending()) {
                        sb.append(" ASC");
                    } else {
                        sb.append(" DESC");
                    }
                    if (i != (orderList.size() - 1)) {
                        sb.append(",");
                    }
                }
                map.put(ORDER_STR, sb.toString());
            }
        }
        return getSqlMapClientTemplate().queryForList(getNamespace() + ".findBetween", map);
    }

    @Override
    public List<Bill> between(Date date1, Date date2, Pagination pagination) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("date1", date1);
        map.put("date2", date2);
        return between(map, pagination);
    }

    @Override
    public List<Bill> between(Date date1, Date date2, String customerId,
                              Pagination pagination) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("date1", date1);
        map.put("date2", date2);
        map.put("customerId", customerId);
        return between(map, pagination);
    }

    @Override
    public int countBetween(Date date1, Date date2) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("date1", date1);
        map.put("date2", date2);
        return (Integer) getSqlMapClientTemplate().queryForObject(getNamespace() + ".countBetween", map);
    }

    @Override
    public int countBetween(Date date1, Date date2, String customerId) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("date1", date1);
        map.put("date2", date2);
        map.put("customerId", customerId);
        return (Integer) getSqlMapClientTemplate().queryForObject(getNamespace() + ".countBetween", map);
    }

}
